package algorithm

import (
	"fmt"
	"path/filepath"
	"time"

	"b2c-delivery-optimization/internal/model"
)

// ChartType 图表类型
type ChartType string

const (
	// WaveChart 波次分布图
	WaveChart ChartType = "wave"
	// PriorityChart 优先级分布图
	PriorityChart ChartType = "priority"
	// LocationChart 位置分布图
	LocationChart ChartType = "location"
	// MetricsChart 算法指标图
	MetricsChart ChartType = "metrics"
)

// VisualizationService 可视化服务
type VisualizationService struct {
	renderer  *ChartRenderer
	outputDir string
}

// NewVisualizationService 创建可视化服务
func NewVisualizationService(outputDir string) *VisualizationService {
	return &VisualizationService{
		renderer:  NewChartRenderer(outputDir),
		outputDir: outputDir,
	}
}

// GenerateCharts 生成所有图表
func (s *VisualizationService) GenerateCharts(waveOrders [][]model.Order, metrics []AlgorithmMetrics) error {
	if len(waveOrders) == 0 {
		return fmt.Errorf("波次订单数据为空")
	}

	// 生成波次分布图
	waveData := s.prepareWaveDistributionData(waveOrders)
	if len(waveData.Values) == 0 {
		return fmt.Errorf("波次分布数据为空")
	}
	if err := s.renderer.RenderBarChart("波次订单分布", "波次", "订单数量", waveData.Labels, waveData.Values, s.GetChartPath(WaveChart)); err != nil {
		return fmt.Errorf("生成波次分布图失败: %v", err)
	}

	// 生成优先级分布图
	priorityData := s.preparePriorityDistributionData(waveOrders)
	if len(priorityData.Values) == 0 {
		return fmt.Errorf("优先级分布数据为空")
	}
	if err := s.renderer.RenderBarChart("订单优先级分布", "优先级", "订单数量", priorityData.Labels, priorityData.Values, s.GetChartPath(PriorityChart)); err != nil {
		return fmt.Errorf("生成优先级分布图失败: %v", err)
	}

	// 生成位置分布图
	locationData := s.prepareLocationDistributionData(waveOrders)
	if len(locationData.XValues) == 0 || len(locationData.YValues) == 0 {
		return fmt.Errorf("位置分布数据为空")
	}
	if err := s.renderer.RenderScatterChart("订单位置分布", "经度", "纬度", locationData.XValues, locationData.YValues, s.GetChartPath(LocationChart)); err != nil {
		return fmt.Errorf("生成位置分布图失败: %v", err)
	}

	// 生成算法指标图
	if len(metrics) > 0 {
		metricsData := s.prepareAlgorithmMetricsData(metrics)
		if err := s.renderer.RenderTimeSeriesChart("算法指标趋势", "迭代次数", "指标值", metricsData.Times, metricsData.SeriesValues, metricsData.Names, s.GetChartPath(MetricsChart)); err != nil {
			return fmt.Errorf("生成算法指标图失败: %v", err)
		}
	}

	return nil
}

// GetChartPath 获取图表文件路径
func (s *VisualizationService) GetChartPath(chartType ChartType) string {
	switch chartType {
	case WaveChart:
		return filepath.Join(s.outputDir, "wave_distribution.png")
	case PriorityChart:
		return filepath.Join(s.outputDir, "priority_distribution.png")
	case LocationChart:
		return filepath.Join(s.outputDir, "location_distribution.png")
	case MetricsChart:
		return filepath.Join(s.outputDir, "algorithm_metrics.png")
	default:
		return ""
	}
}

// ValidateChartType 验证图表类型
func (s *VisualizationService) ValidateChartType(chartType ChartType) bool {
	switch chartType {
	case WaveChart, PriorityChart, LocationChart, MetricsChart:
		return true
	default:
		return false
	}
}

// ChartData 图表数据结构
type ChartData struct {
	Labels       []string
	Values       []float64
	XValues      []float64
	YValues      []float64
	Times        []time.Time
	SeriesValues [][]float64
	Names        []string
}

// prepareWaveDistributionData 准备波次分布数据
func (s *VisualizationService) prepareWaveDistributionData(waveOrders [][]model.Order) *ChartData {
	labels := make([]string, len(waveOrders))
	values := make([]float64, len(waveOrders))

	for i, orders := range waveOrders {
		labels[i] = fmt.Sprintf("Wave %d", i+1)
		values[i] = float64(len(orders))
	}

	return &ChartData{
		Labels: labels,
		Values: values,
	}
}

// preparePriorityDistributionData 准备优先级分布数据
func (s *VisualizationService) preparePriorityDistributionData(waveOrders [][]model.Order) *ChartData {
	priorityMap := make(map[int]int)
	for _, wave := range waveOrders {
		for _, order := range wave {
			priorityMap[order.Priority]++
		}
	}

	labels := make([]string, len(priorityMap))
	values := make([]float64, len(priorityMap))
	i := 0
	for priority, count := range priorityMap {
		labels[i] = fmt.Sprintf("P%d", priority)
		values[i] = float64(count)
		i++
	}

	return &ChartData{
		Labels: labels,
		Values: values,
	}
}

// prepareLocationDistributionData 准备位置分布数据
func (s *VisualizationService) prepareLocationDistributionData(waveOrders [][]model.Order) *ChartData {
	var xValues, yValues []float64
	for _, wave := range waveOrders {
		for _, order := range wave {
			xValues = append(xValues, order.Location.Longitude)
			yValues = append(yValues, order.Location.Latitude)
		}
	}

	return &ChartData{
		XValues: xValues,
		YValues: yValues,
	}
}

// prepareAlgorithmMetricsData 准备算法指标数据
func (s *VisualizationService) prepareAlgorithmMetricsData(metrics []AlgorithmMetrics) *ChartData {
	times := make([]time.Time, len(metrics))
	seriesValues := make([][]float64, 3) // 3个指标：优先级得分、位置得分、平衡得分
	names := []string{"优先级得分", "位置得分", "平衡得分"}

	// 初始化每个指标的切片
	for i := range seriesValues {
		seriesValues[i] = make([]float64, len(metrics))
	}

	for i, metric := range metrics {
		times[i] = metric.Timestamp
		seriesValues[0][i] = metric.PriorityScore
		seriesValues[1][i] = metric.LocationScore
		seriesValues[2][i] = metric.BalanceScore
	}

	return &ChartData{
		Times:        times,
		SeriesValues: seriesValues,
		Names:        names,
	}
}
